<html>
<head><meta charset="utf-8"><title>Should repr(C) enum allow unknown discriminants? · t-lang/wg-unsafe-code-guidelines · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/index.html">t-lang/wg-unsafe-code-guidelines</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Should.20repr(C).20enum.20allow.20unknown.20discriminants.3F.html">Should repr(C) enum allow unknown discriminants?</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="198043130"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Should%20repr%28C%29%20enum%20allow%20unknown%20discriminants%3F/near/198043130" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Elichai Turkel <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Should.20repr(C).20enum.20allow.20unknown.20discriminants.3F.html#198043130">(May 19 2020 at 09:49)</a>:</h4>
<p>Hi,<br>
Unlike C/C++ regular enums(not enum classes) in rust enums require an instance of an enum to have a valid discriminant. <br>
Currently passing a <code>repr(C) enum</code> from rust to C/C++ should be completely safe.<br>
But the reverse might not be, because if the enums get out of sync and you pass a discriminant you haven't updated yet in rust you get UB.<br>
Not only that but regular enums in C/C++ you can easily write whatever int value you want into an enum instance (<a href="https://godbolt.org/z/oeZ2Be">https://godbolt.org/z/oeZ2Be</a>)<br>
So passing a <code>&amp;mut c_enum_instance</code> into a C/C++ function is also very dangerous.<br>
This is really footgunny IMHO</p>
<p>Maybe we should somehow drop this requirement(for repr(c)) / allow some <code>Other</code> variant to be added that captures all the unknown discriminants or something else</p>
<p>Some existing discussions I've found:<br>
<a href="https://github.com/rust-lang/rust-bindgen/issues/225">https://github.com/rust-lang/rust-bindgen/issues/225</a><br>
<a href="https://github.com/google/flatbuffers/issues/5467">https://github.com/google/flatbuffers/issues/5467</a></p>



<a name="198046306"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Should%20repr%28C%29%20enum%20allow%20unknown%20discriminants%3F/near/198046306" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Peter Rabbit <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Should.20repr(C).20enum.20allow.20unknown.20discriminants.3F.html#198046306">(May 19 2020 at 10:26)</a>:</h4>
<p>This is why <code>winapi</code> defines enums as mere typedefs to <code>u32</code> and the variants as plain integer constants. That and it helps to save on compile time. Also C has a habit of using enums as bitflags and reimplementing all the operators to allow bitwise operations would also take up valuable compile time.</p>



<a name="198249265"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Should%20repr%28C%29%20enum%20allow%20unknown%20discriminants%3F/near/198249265" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Should.20repr(C).20enum.20allow.20unknown.20discriminants.3F.html#198249265">(May 20 2020 at 19:57)</a>:</h4>
<p>then we'd lose all layout optimizations for these enums though</p>



<a name="198249337"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Should%20repr%28C%29%20enum%20allow%20unknown%20discriminants%3F/near/198249337" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Should.20repr(C).20enum.20allow.20unknown.20discriminants.3F.html#198249337">(May 20 2020 at 19:58)</a>:</h4>
<p>and there's probably a good use-case for enums with validity requirements but a guaranteed layout, which is what <code>repr(C)</code> currently does</p>



<a name="198249352"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Should%20repr%28C%29%20enum%20allow%20unknown%20discriminants%3F/near/198249352" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Should.20repr(C).20enum.20allow.20unknown.20discriminants.3F.html#198249352">(May 20 2020 at 19:58)</a>:</h4>
<p>I agree the <code>C</code> is a misnomer though...</p>



<a name="198249434"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Should%20repr%28C%29%20enum%20allow%20unknown%20discriminants%3F/near/198249434" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Should.20repr(C).20enum.20allow.20unknown.20discriminants.3F.html#198249434">(May 20 2020 at 19:59)</a>:</h4>
<p>I dont think we should "allow other variants", at that point it's not an <code>enum</code> in the Rust sense any more but an integer.<br>
but I could imagine renaming <code>repr(C)</code> to something else (<code>repr(union_of_structs)</code> anyone?) to avoid the confusion.</p>



<a name="198256232"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Should%20repr%28C%29%20enum%20allow%20unknown%20discriminants%3F/near/198256232" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Chris Denton <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Should.20repr(C).20enum.20allow.20unknown.20discriminants.3F.html#198256232">(May 20 2020 at 20:56)</a>:</h4>
<p>I think it would be better to have a <code>cnum</code> (?) type. Rust <code>enum</code> and C <code>enum</code> have little in common IMHO.</p>



<a name="198269605"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Should%20repr%28C%29%20enum%20allow%20unknown%20discriminants%3F/near/198269605" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Gary Guo <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Should.20repr(C).20enum.20allow.20unknown.20discriminants.3F.html#198269605">(May 20 2020 at 23:22)</a>:</h4>
<p><span class="user-mention silent" data-user-id="260325">Chris Denton</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/Should.20repr(C).20enum.20allow.20unknown.20discriminants.3F/near/198256232">said</a>:</p>
<blockquote>
<p>I think it would be better to have a <code>cnum</code> (?) type. Rust <code>enum</code> and C <code>enum</code> have little in common IMHO.</p>
</blockquote>
<p>Wouldn't a wrapper type with associated constants do the same?</p>



<a name="198270385"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Should%20repr%28C%29%20enum%20allow%20unknown%20discriminants%3F/near/198270385" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Chris Denton <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Should.20repr(C).20enum.20allow.20unknown.20discriminants.3F.html#198270385">(May 20 2020 at 23:33)</a>:</h4>
<p>Sure! My point was that I don't think there's a need to mess about with <code>repr</code> for this.</p>



<a name="198297246"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Should%20repr%28C%29%20enum%20allow%20unknown%20discriminants%3F/near/198297246" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Should.20repr(C).20enum.20allow.20unknown.20discriminants.3F.html#198297246">(May 21 2020 at 08:26)</a>:</h4>
<p><span class="user-mention silent" data-user-id="260325">Chris Denton</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/Should.20repr(C).20enum.20allow.20unknown.20discriminants.3F/near/198270385">said</a>:</p>
<blockquote>
<p>Sure! My point was that I don't think there's a need to mess about with <code>repr</code> for this.</p>
</blockquote>
<p>well, messing around with <code>repr</code> is the only way we can solve the problem that people regularly think that <code>repr(C)</code> enums are similar to <code>C</code> enums. That's not an unreasonable assumption, after all -- but it's just wrong.</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>